// sqdll.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"

extern "C" {
#include "squirrel.h"
}

#include "sqdll.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//
//	Note!
//
//		If this DLL is dynamically linked against the MFC
//		DLLs, any functions exported from this DLL which
//		call into MFC must have the AFX_MANAGE_STATE macro
//		added at the very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//

// CsqdllApp

BEGIN_MESSAGE_MAP(CsqdllApp, CWinApp)
END_MESSAGE_MAP()


// CsqdllApp construction

CsqdllApp::CsqdllApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}


// The one and only CsqdllApp object

CsqdllApp theApp;


// CsqdllApp initialization

BOOL CsqdllApp::InitInstance()
{
	CWinApp::InitInstance();

	return TRUE;
}

SQInteger SetString(HSQUIRRELVM vm, SQChar *name, const SQChar *value);
SQInteger SetInteger(HSQUIRRELVM vm, SQChar *name, SQInteger value);

// Create and Destroy the VM

__declspec(dllexport) CSquirrelVM* Sqvm_Create()
{
	CSquirrelVM *vm = new CSquirrelVM();
	return vm;
}
__declspec(dllexport) void Sqvm_Destroy(CSquirrelVM* vm)
{
	if (vm != NULL)
	{
		vm->Close();
		delete vm;
	}
}


// CSquirrelVM Methods
CSquirrelVM::CSquirrelVM()
{
	_vm = NULL;
}

// Open and Close the VM
HSQUIRRELVM CSquirrelVM::GetVM()
{
	return _vm;
}
void CSquirrelVM::Open(int initialStackSize)
{
	_vm = sq_open(initialStackSize);
	this->PushRootTable();
	int top = this->GetTop();
	this->PushUserPointer(this);
	this->PushString("@__SQVM__@", 10);
	this->CreateSlot(top);
	//_prnFnInternal = &CSquirrelVM::PrintInternal;
	//_errFnInternal = &CSquirrelVM::ErrorInternal;
	//sq_setprintfunc(_vm, _prnFnInternal, _errFnInternal);
}
bool CSquirrelVM::IsOpen()
{
	return _vm != NULL;
}
void CSquirrelVM::Close()
{
	if ( _vm != NULL )
		sq_close(_vm);
	_vm = NULL;
}


/*
** Print Functions
*/
void CSquirrelVM::PrintInternal(HSQUIRRELVM,const SQChar * ,...)
{
	if ( this->_prnFnExternal == NULL )
		return;
}
void CSquirrelVM::ErrorInternal(HSQUIRRELVM,const SQChar * ,...)
{
	if ( this->_errFnExternal == NULL )
		return;
}


SQUserPointer CSquirrelVM::GetForeignPtr()
{
	return sq_getforeignptr(_vm);
}
SQUserPointer CSquirrelVM::GetPrintFunc()
{
	return sq_getprintfunc(_vm);
}
SQUserPointer CSquirrelVM::GetErrorFunc()
{
	return sq_geterrorfunc(_vm);
}


SQInteger CSquirrelVM::GetVMState()
{
	return sq_getvmstate(_vm);
}

void CSquirrelVM::Move(CSquirrelVM* tarVM, SQInteger idx)
{
	return sq_move( _vm, tarVM->_vm, idx);
}

CSquirrelVM* CSquirrelVM::NewThread(CSquirrelVM* friendvm, SQInteger intialStackSize)
{
	// FIXME:
	return NULL;
	//return sq_newthread( friendvm, intialStackSize );
}


void CSquirrelVM::PushRegistryTable()
{
	sq_pushregistrytable(_vm);
}

void CSquirrelVM::PushRootTable()
{
	sq_pushroottable(_vm);
}

void CSquirrelVM::SetErrorHandler()
{
	sq_seterrorhandler(_vm);
}

void CSquirrelVM::SetForeignPtr(SQUserPointer p)
{
	sq_setforeignptr(_vm, p);
}

void CSquirrelVM::SetPrintFunc(SQVM_EXTERN_PRINT_FN prnFn, SQVM_EXTERN_PRINT_FN errFn)
{
	this->_prnFnExternal = prnFn;
	this->_errFnExternal = errFn;
}

void CSquirrelVM::SetRootTable()
{
	sq_setroottable(_vm);
}

SQRESULT CSquirrelVM::SuspendVM()
{
	return sq_suspendvm(_vm);
}

SQRESULT CSquirrelVM::WakeUpVM(SQBool resumedret, SQBool retval, SQBool RaiseError,SQBool ThrowError)
{
	return sq_wakeupvm( _vm, resumedret, retval, RaiseError, ThrowError );
}

/*
** COMPILER
*/
SQRESULT CSquirrelVM::CompileReader(SQLEXREADFUNC ReadFunc, SQUserPointer UserPtr, char *SourceName, SQBool RaiseError )
{
	return sq_compile( _vm, ReadFunc, UserPtr, SourceName, RaiseError);
}
SQRESULT CSquirrelVM::CompileBuffer(char *Buffer, int BufferSize, char *SourceName, SQBool RaiseError )
{
	return sq_compilebuffer( _vm, Buffer, BufferSize, SourceName, RaiseError);
}
void CSquirrelVM::EnableDebugInfo(SQBool DebugInfo )
{
	sq_enabledebuginfo( _vm, DebugInfo );
}
void CSquirrelVM::SetCompilerErrorHandler(SQCOMPILERERROR f )
{
	sq_setcompilererrorhandler( _vm, f );
}

/*
** STACK OPERATIONS
*/


SQInteger CSquirrelVM::Cmp()
{
	return sq_cmp(_vm);
}
SQInteger CSquirrelVM::GetTop()
{
	return sq_gettop(_vm);
}
void CSquirrelVM::Pop(SQInteger Count)
{
	sq_pop(_vm,Count);
}
void CSquirrelVM::PopTop()
{
	sq_poptop(_vm);
}
void CSquirrelVM::Push(SQInteger Count)
{
	sq_push(_vm,Count);
}
void CSquirrelVM::Remove(SQInteger Count)
{
	sq_remove(_vm,Count);
}
void CSquirrelVM::ReserveStack(SQInteger Count)
{
	sq_reservestack(_vm,Count);
}

void CSquirrelVM::SetTop(SQInteger Count)
{
	sq_settop(_vm,Count);
}


/*
** Object Creation and Handling
*/

SQRESULT CSquirrelVM::CreateInstance(SQInteger Idx)
{
	return sq_createinstance( _vm, Idx );
}
SQRESULT CSquirrelVM::GetBool(SQInteger Idx, SQBool *Result)
{
	return sq_getbool( _vm, Idx, Result);
}
SQRESULT CSquirrelVM::GetClosureInfo(SQInteger Idx, SQUnsignedInteger *nparams,	SQUnsignedInteger *nfreevars)
{
	return sq_getclosureinfo( _vm, Idx, nparams, nfreevars );
}

SQRESULT CSquirrelVM::GetFloat(SQInteger Idx, SQFloat *Result)
{
	return sq_getfloat( _vm, Idx, Result);
}
SQRESULT CSquirrelVM::GetInstanceUp(SQInteger Idx,  SQUserPointer *up, SQUserPointer typeTag )
{
	return sq_getinstanceup( _vm, Idx, up, typeTag);
}
SQRESULT CSquirrelVM::GetInteger(SQInteger Idx, SQInteger *Result)
{
	return sq_getinteger( _vm, Idx, Result);
}
SQChar * CSquirrelVM::GetScratchPad(SQInteger minsize)
{
	return sq_getscratchpad( _vm, minsize );
}
SQInteger CSquirrelVM::GetSize(SQInteger Idx)
{
	return sq_getsize( _vm, Idx);
}
SQInteger CSquirrelVM::GetString(SQInteger Idx, const SQChar **c)
{
	return sq_getstring( _vm, Idx, c);
}
SQInteger CSquirrelVM::GetThread(SQInteger Idx, HSQUIRRELVM *v)
{
	return sq_getthread( _vm, Idx, v);
}
SQObjectType CSquirrelVM::GetType(SQInteger Idx)
{
	return sq_gettype( _vm, Idx );
}
SQRESULT CSquirrelVM::GetTypeTag(SQInteger Idx, SQUserPointer *typetag)
{
	return sq_gettypetag( _vm, Idx, typetag );
}
SQRESULT CSquirrelVM::GetUserData(SQInteger Idx, SQUserPointer *p, SQUserPointer *typetag)
{
	return sq_getuserdata( _vm, Idx, p, typetag );
}
SQRESULT CSquirrelVM::GetUserPointer(SQInteger Idx, SQUserPointer *p)
{
	return sq_getuserpointer( _vm, Idx, p );
}
void CSquirrelVM::NewArray(SQInteger Size)
{
	sq_newarray( _vm, Size );
}
SQRESULT CSquirrelVM::NewClass(SQBool HasBaseClass)
{
	return sq_newclass( _vm, HasBaseClass );
}
void CSquirrelVM::NewClosure(SQFUNCTION func, SQInteger nfreevars )
{
	sq_newclosure( _vm, func, nfreevars );
}
void CSquirrelVM::NewTable()
{
	sq_newtable( _vm );
}
SQUserPointer CSquirrelVM::NewUserData(SQUnsignedInteger Size)
{
	return sq_newuserdata( _vm, Size );
}
void CSquirrelVM::PushBool(SQBool Value )
{
	sq_pushbool( _vm, Value );
}
void CSquirrelVM::PushFloat(SQFloat Value )
{
	sq_pushfloat( _vm, Value );
}
void CSquirrelVM::PushInteger(SQInteger Value )
{
	sq_pushinteger( _vm, Value );
}
void CSquirrelVM::PushNull()
{
	sq_pushnull( _vm );
}
void CSquirrelVM::PushString(const SQChar *s, SQInteger len)
{
	sq_pushstring( _vm, s, len );
}
void CSquirrelVM::PushUserPointer(SQUserPointer p)
{
	sq_pushuserpointer( _vm, p );
}
SQRESULT CSquirrelVM::SetInstanceUp(SQInteger Idx, SQUserPointer up)
{
	return sq_setinstanceup( _vm, Idx, up );
}
SQRESULT CSquirrelVM::SetNativeClosureName(SQInteger Idx, const SQChar *name)
{
	return sq_setnativeclosurename( _vm, Idx, name );
}
SQRESULT CSquirrelVM::SetParamsCheck(SQInteger nparamscheck, const SQChar *TypeMask)
{
	return sq_setparamscheck( _vm, nparamscheck, TypeMask );
}
void CSquirrelVM::SetReleaseHook(SQInteger Idx, SQRELEASEHOOK Hook)
{
	sq_setreleasehook( _vm, Idx, Hook );
}
SQRESULT CSquirrelVM::SetTypeTag(SQInteger Idx, SQUserPointer TypeTag)
{
	return sq_settypetag( _vm, Idx, TypeTag );
}
SQRESULT CSquirrelVM::Call(SQInteger Params, SQBool RetVal, SQBool RaiseError)
{
	return sq_call( _vm, Params, RetVal, RaiseError );
}
void CSquirrelVM::GetLastError()
{
	sq_getlasterror( _vm );
}
const SQChar * CSquirrelVM::GetLocal(SQUnsignedInteger level, SQUnsignedInteger nseq )
{
	return sq_getlocal( _vm, level, nseq );
}
void CSquirrelVM::ResetError()
{
	sq_reseterror(_vm);
}
SQRESULT CSquirrelVM::Resume(SQBool RetVal, SQBool RaiseError)
{
	return sq_resume( _vm, RetVal, RaiseError );
}
SQRESULT CSquirrelVM::ThrowError(const SQChar *err)
{
	return sq_throwerror( _vm, err );
}


/*
** OBJECTS MANIPULATION
*/
SQRESULT CSquirrelVM::ArrayAppend(SQInteger Idx)
{
	return sq_arrayappend( _vm, Idx );
}
SQRESULT CSquirrelVM::ArrayPop(SQInteger Idx, SQBool PushVal )
{
	return sq_arraypop( _vm, Idx, PushVal );
}
SQRESULT CSquirrelVM::ArrayResize(SQInteger Idx, SQInteger NewSize )
{
	return sq_arrayresize( _vm, Idx, NewSize );
}
SQRESULT CSquirrelVM::ArrayReverse(SQInteger Idx )
{
	return sq_arrayreverse( _vm, Idx );
}
SQRESULT CSquirrelVM::Clone(SQInteger Idx )
{
	return sq_clone( _vm, Idx );
}
SQRESULT CSquirrelVM::CreateSlot(SQInteger Idx )
{
	return sq_createslot( _vm, Idx );
}
SQRESULT CSquirrelVM::DeleteSlot(SQInteger Idx, SQBool PushValue )
{
	return sq_deleteslot( _vm, Idx, PushValue );
}
SQRESULT CSquirrelVM::Get(SQInteger Idx )
{
	return sq_get( _vm, Idx );
}
SQRESULT CSquirrelVM::GetAttributes(SQInteger Idx )
{
	return sq_getattributes( _vm, Idx );
}
SQRESULT CSquirrelVM::GetClass(SQInteger Idx )
{
	return sq_getclass( _vm, Idx );
}
SQRESULT CSquirrelVM::GetDelegate(SQInteger Idx )
{
	return sq_getdelegate( _vm, Idx );
}
const SQChar * CSquirrelVM::GetFreeVariable(SQInteger Idx, SQInteger nval )
{
	return sq_getfreevariable( _vm, Idx, nval );
}
SQRESULT CSquirrelVM::GetWeakRefVal(SQInteger Idx )
{
	return sq_getweakrefval( _vm, Idx );
}
SQRESULT CSquirrelVM::Next(SQInteger Idx )
{
	return sq_next( _vm, Idx );
}
SQRESULT CSquirrelVM::RawDeleteSlot(SQInteger Idx, SQBool PushVal )
{
	return sq_rawdeleteslot( _vm, Idx, PushVal );
}
SQRESULT CSquirrelVM::RawGet(SQInteger Idx )
{
	return sq_rawget( _vm, Idx );
}
SQRESULT CSquirrelVM::RawSet(SQInteger Idx )
{
	return sq_rawset( _vm, Idx );
}
SQRESULT CSquirrelVM::Set(SQInteger Idx )
{
	return sq_set( _vm, Idx );
}
SQRESULT CSquirrelVM::SetAttributes(SQInteger Idx )
{
	return sq_setattributes( _vm, Idx );
}
SQRESULT CSquirrelVM::SetDelegate(SQInteger Idx )
{
	return sq_setdelegate( _vm, Idx );
}
SQRESULT CSquirrelVM::SetFreeVariable(SQInteger Idx, SQInteger nval )
{
	return sq_setfreevariable( _vm, Idx, nval );
}
void CSquirrelVM::WeakRef(SQInteger Idx )
{
	sq_weakref( _vm, Idx );
}


/*
** ByteCode Serialization
*/
SQRESULT CSquirrelVM::ReadClosure(SQREADFUNC readf, SQUserPointer up)
{
	return sq_readclosure( _vm, readf, up );
}
SQRESULT CSquirrelVM::WriteClosure(SQWRITEFUNC writef, SQUserPointer up)
{
	return sq_readclosure( _vm, writef, up );
}

/*
** RAW OBJECT HANDLING
*/
void CSquirrelVM::AddRef(HSQOBJECT *po)
{
	sq_addref( _vm, po);
}
/* FIXME: ???
SQRESULT CSquirrelVM::GetObjTypeTag(HSQOBJECT *o, SQUserPointer *typetag)
{
	return sq_getobjtypetag( o, typetag);
}
*/
SQRESULT CSquirrelVM::GetStackObj(SQInteger Idx, HSQOBJECT *po)
{
	return sq_getstackobj( _vm, Idx, po );
}
SQBool CSquirrelVM::ObjToBool(HSQOBJECT *po)
{
	return sq_objtobool( po );
}
SQFloat CSquirrelVM::ObjToFloat(HSQOBJECT *po)
{
	return sq_objtofloat( po );
}
SQInteger CSquirrelVM::ObjToInteger(HSQOBJECT *po)
{
	return sq_objtointeger( po );
}
const SQChar * CSquirrelVM::ObjToString(HSQOBJECT *po)
{
	return sq_objtostring( po );
}
void CSquirrelVM::PushObject(HSQOBJECT obj)
{
	sq_pushobject( _vm, obj );
}
SQBool CSquirrelVM::Release(HSQOBJECT *po)
{
	return sq_release( _vm, po );
}
void CSquirrelVM::ResetObject(HSQOBJECT *po)
{
	sq_resetobject( po );
}

/*
** DEBUG INTERFACE
*/
void CSquirrelVM::SetDebugHook()
{
	sq_setdebughook( _vm );
}
SQRESULT CSquirrelVM::StackInfos(SQInteger Idx, SQStackInfos *si)
{
	return sq_stackinfos( _vm, Idx, si );
}

/*
** Success Failed API
*/
bool CSquirrelVM::Success(SQRESULT result)
{
	return SQ_SUCCEEDED(result);
}
bool CSquirrelVM::Failed(SQRESULT result)
{
	return SQ_FAILED(result);
}


/*
**
** SQVM API EXPOSED
**
*/
__declspec(dllexport) void Sqvm_Close(CSquirrelVM* vmc)
{
	sq_close(vmc->GetVM());
}

__declspec(dllexport) SQUserPointer Sqvm_GetForeignPtr(CSquirrelVM* vmc)
{
	return sq_getforeignptr(vmc->GetVM());
}

__declspec(dllexport) SQPRINTFUNCTION Sqvm_GetPrintFunc(CSquirrelVM* vmc)
{
	return sq_getprintfunc(vmc->GetVM());
}

__declspec(dllexport) SQPRINTFUNCTION Sqvm_GetErrorFunc(CSquirrelVM* vmc)
{
	return sq_geterrorfunc(vmc->GetVM());
}

__declspec(dllexport) SQInteger Sqvm_GetVMState(CSquirrelVM* vmc)
{
	return sq_getvmstate(vmc->GetVM());
}

__declspec(dllexport) void Sqvm_Move(HSQUIRRELVM srcVM, HSQUIRRELVM tarVM, SQInteger idx)
{
	return sq_move( srcVM, tarVM, idx);
}

__declspec(dllexport) HSQUIRRELVM Sqvm_NewThread(HSQUIRRELVM friendvm, SQInteger intialStackSize)
{
	return sq_newthread( friendvm, intialStackSize );
}

__declspec(dllexport) HSQUIRRELVM Sqvm_Open( int StackSize )
{
	return sq_open( StackSize );
}

__declspec(dllexport) void Sqvm_PushRegistryTable(CSquirrelVM* vmc)
{
	sq_pushregistrytable( vmc->GetVM() );
}

__declspec(dllexport) void Sqvm_PushRootTable(CSquirrelVM* vmc)
{
	sq_pushroottable( vmc->GetVM() );
}

__declspec(dllexport) void Sqvm_SetErrorHandler(CSquirrelVM* vmc)
{
	sq_seterrorhandler( vmc->GetVM() );
}

__declspec(dllexport) void Sqvm_SetForeignPtr(CSquirrelVM* vmc, SQUserPointer p)
{
	sq_setforeignptr(vmc->GetVM(), p);
}

__declspec(dllexport) void Sqvm_SetPrintFunc(CSquirrelVM* vmc, SQPRINTFUNCTION prnFn, SQPRINTFUNCTION errFn)
{
	sq_setprintfunc(vmc->GetVM(), prnFn, errFn);
}

__declspec(dllexport) void Sqvm_SetRootTable(CSquirrelVM* vmc)
{
	sq_setroottable( vmc->GetVM() );
}

__declspec(dllexport) SQRESULT Sqvm_SuspendVM(CSquirrelVM* vmc)
{
	return sq_suspendvm( vmc->GetVM() );
}

__declspec(dllexport) SQRESULT Sqvm_WakeUpVM(CSquirrelVM* vmc, SQBool resumedret, SQBool retval, SQBool RaiseError,SQBool ThrowError)
{
	return sq_wakeupvm( vmc->GetVM(), resumedret, retval, RaiseError, ThrowError );
}

/*
** COMPILER
*/
__declspec(dllexport) SQRESULT Sqvm_CompileReader(CSquirrelVM* vmc, SQLEXREADFUNC ReadFunc, SQUserPointer UserPtr, char *SourceName, SQBool RaiseError )
{
	return sq_compile( vmc->GetVM(), ReadFunc, UserPtr, SourceName, RaiseError);
}
__declspec(dllexport) SQRESULT Sqvm_CompileBuffer(CSquirrelVM* vmc, char *Buffer, int BufferSize, char *SourceName, SQBool RaiseError )
{
	return sq_compilebuffer( vmc->GetVM(), Buffer, BufferSize, SourceName, RaiseError);
}
__declspec(dllexport) void Sqvm_EnableDebugInfo(CSquirrelVM* vmc, SQBool DebugInfo )
{
	sq_enabledebuginfo( vmc->GetVM(), DebugInfo );
}
__declspec(dllexport) void Sqvm_SetCompilerErrorHandler(CSquirrelVM* vmc, SQCOMPILERERROR f )
{
	sq_setcompilererrorhandler( vmc->GetVM(), f );
}

/*
** STACK OPERATIONS
*/


__declspec(dllexport) SQInteger Sqvm_Cmp(CSquirrelVM* vmc)
{
	return sq_cmp( vmc->GetVM() );
}
__declspec(dllexport) SQInteger Sqvm_GetTop(CSquirrelVM* vmc)
{
	return sq_gettop( vmc->GetVM() );
}
__declspec(dllexport) void Sqvm_Pop(CSquirrelVM* vmc, SQInteger Count)
{
	sq_pop( vmc->GetVM(), Count );
}
__declspec(dllexport) void Sqvm_PopTop(CSquirrelVM* vmc)
{
	sq_poptop( vmc->GetVM() );
}
__declspec(dllexport) void Sqvm_Push(CSquirrelVM* vmc, SQInteger Count)
{
	sq_push( vmc->GetVM(), Count );
}
__declspec(dllexport) void Sqvm_Remove(CSquirrelVM* vmc, SQInteger Count)
{
	sq_remove( vmc->GetVM(), Count );
}
__declspec(dllexport) void Sqvm_ReserveStack(CSquirrelVM* vmc, SQInteger Count)
{
	sq_reservestack( vmc->GetVM(), Count );
}

__declspec(dllexport) void Sqvm_SetTop(CSquirrelVM* vmc, SQInteger Count)
{
	sq_settop( vmc->GetVM(), Count );
}


/*
** Object Creation and Handling
*/

__declspec(dllexport) SQRESULT Sqvm_CreateInstance(CSquirrelVM* vmc, SQInteger Idx)
{
	return sq_createinstance( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_GetBool(CSquirrelVM* vmc, SQInteger Idx, SQBool *Result)
{
	return sq_getbool( vmc->GetVM(), Idx, Result);
}
__declspec(dllexport) SQRESULT Sqvm_GetClosureInfo(CSquirrelVM* vmc, SQInteger Idx, 
												SQUnsignedInteger *nparams,
												SQUnsignedInteger *nfreevars)
{
	return sq_getclosureinfo( vmc->GetVM(), Idx, nparams, nfreevars );
}

__declspec(dllexport) SQRESULT Sqvm_GetFloat(CSquirrelVM* vmc, SQInteger Idx, SQFloat *Result)
{
	return sq_getfloat( vmc->GetVM(), Idx, Result);
}
__declspec(dllexport) SQRESULT Sqvm_GetInstanceUp(CSquirrelVM* vmc, SQInteger Idx, 
											   SQUserPointer *up, SQUserPointer typeTag )
{
	return sq_getinstanceup( vmc->GetVM(), Idx, up, typeTag);
}
__declspec(dllexport) SQRESULT Sqvm_GetInteger(CSquirrelVM* vmc, SQInteger Idx, SQInteger *Result)
{
	return sq_getinteger( vmc->GetVM(), Idx, Result);
}
__declspec(dllexport) SQChar * Sqvm_GetScratchPad(CSquirrelVM* vmc, SQInteger minsize)
{
	return sq_getscratchpad( vmc->GetVM(), minsize );
}
__declspec(dllexport) SQInteger Sqvm_GetSize(CSquirrelVM* vmc, SQInteger Idx)
{
	return sq_getsize( vmc->GetVM(), Idx);
}
__declspec(dllexport) SQInteger Sqvm_GetString(CSquirrelVM* vmc, SQInteger Idx, const SQChar **c)
{
	return sq_getstring( vmc->GetVM(), Idx, c);
}
__declspec(dllexport) SQInteger Sqvm_GetThread(CSquirrelVM* vmc, SQInteger Idx, HSQUIRRELVM *v)
{
	return sq_getthread( vmc->GetVM(), Idx, v);
}
__declspec(dllexport) SQObjectType Sqvm_GetType(CSquirrelVM* vmc, SQInteger Idx)
{
	return sq_gettype( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_GetTypeTag(CSquirrelVM* vmc, SQInteger Idx, SQUserPointer *typetag)
{
	return sq_gettypetag( vmc->GetVM(), Idx, typetag );
}
__declspec(dllexport) SQRESULT Sqvm_GetUserData(CSquirrelVM* vmc, SQInteger Idx, 
											 SQUserPointer *p, SQUserPointer *typetag)
{
	return sq_getuserdata( vmc->GetVM(), Idx, p, typetag );
}
__declspec(dllexport) SQRESULT Sqvm_GetUserPointer(CSquirrelVM* vmc, SQInteger Idx, SQUserPointer *p)
{
	return sq_getuserpointer( vmc->GetVM(), Idx, p );
}
__declspec(dllexport) void Sqvm_NewArray(CSquirrelVM* vmc, SQInteger Size)
{
	sq_newarray( vmc->GetVM(), Size );
}
__declspec(dllexport) SQRESULT Sqvm_NewClass(CSquirrelVM* vmc, SQBool HasBaseClass)
{
	return sq_newclass( vmc->GetVM(), HasBaseClass );
}
__declspec(dllexport) void Sqvm_NewClosure(CSquirrelVM* vmc, SQFUNCTION func, SQInteger nfreevars )
{
	sq_newclosure( vmc->GetVM(), func, nfreevars );
}
__declspec(dllexport) void Sqvm_NewTable(CSquirrelVM* vmc)
{
	sq_newtable( vmc->GetVM() );
}
__declspec(dllexport) SQUserPointer Sqvm_NewUserData(CSquirrelVM* vmc, SQUnsignedInteger Size)
{
	return sq_newuserdata( vmc->GetVM(), Size );
}
__declspec(dllexport) void Sqvm_PushBool(CSquirrelVM* vmc, SQBool Value )
{
	sq_pushbool( vmc->GetVM(), Value );
}
__declspec(dllexport) void Sqvm_PushFloat(CSquirrelVM* vmc, SQFloat Value )
{
	sq_pushfloat( vmc->GetVM(), Value );
}
__declspec(dllexport) void Sqvm_PushInteger(CSquirrelVM* vmc, SQInteger Value )
{
	sq_pushinteger( vmc->GetVM(), Value );
}
__declspec(dllexport) void Sqvm_PushNull(CSquirrelVM* vmc)
{
	sq_pushnull( vmc->GetVM() );
}
__declspec(dllexport) void Sqvm_PushString(CSquirrelVM* vmc, const SQChar *s, SQInteger len)
{
	sq_pushstring( vmc->GetVM(), s, len );
}
__declspec(dllexport) void Sqvm_PushUserPointer(CSquirrelVM* vmc, SQUserPointer p)
{
	sq_pushuserpointer( vmc->GetVM(), p );
}
__declspec(dllexport) SQRESULT Sqvm_SetInstanceUp(CSquirrelVM* vmc, SQInteger Idx, SQUserPointer up)
{
	return sq_setinstanceup( vmc->GetVM(), Idx, up );
}
__declspec(dllexport) SQRESULT Sqvm_SetNativeClosureName(CSquirrelVM* vmc, SQInteger Idx, const SQChar *name)
{
	return sq_setnativeclosurename( vmc->GetVM(), Idx, name );
}
__declspec(dllexport) SQRESULT Sqvm_SetParamsCheck(CSquirrelVM* vmc, SQInteger nparamscheck, const SQChar *TypeMask)
{
	return sq_setparamscheck( vmc->GetVM(), nparamscheck, TypeMask );
}
__declspec(dllexport) void Sqvm_SetReleaseHook(CSquirrelVM* vmc, SQInteger Idx, SQRELEASEHOOK Hook)
{
	sq_setreleasehook( vmc->GetVM(), Idx, Hook );
}
__declspec(dllexport) SQRESULT Sqvm_SetTypeTag(CSquirrelVM* vmc, SQInteger Idx, SQUserPointer TypeTag)
{
	return sq_settypetag( vmc->GetVM(), Idx, TypeTag );
}
__declspec(dllexport) SQRESULT Sqvm_Call(CSquirrelVM* vmc, SQInteger Params, SQBool RetVal, SQBool RaiseError)
{
	return sq_call( vmc->GetVM(), Params, RetVal, RaiseError );
}
__declspec(dllexport) void Sqvm_GetLastError(CSquirrelVM* vmc)
{
	sq_getlasterror( vmc->GetVM() );
}
__declspec(dllexport) const SQChar * Sqvm_GetLocal(CSquirrelVM* vmc, 
												SQUnsignedInteger level, 
												SQUnsignedInteger nseq )
{
	return sq_getlocal( vmc->GetVM(), level, nseq );
}
__declspec(dllexport) void Sqvm_ResetError(CSquirrelVM* vmc)
{
	sq_reseterror( vmc->GetVM() );
}
__declspec(dllexport) SQRESULT Sqvm_Resume(CSquirrelVM* vmc, SQBool RetVal, SQBool RaiseError)
{
	return sq_resume( vmc->GetVM(), RetVal, RaiseError );
}
__declspec(dllexport) SQRESULT Sqvm_ThrowError(CSquirrelVM* vmc, const SQChar *err)
{
	return sq_throwerror( vmc->GetVM(), err );
}


/*
** OBJECTS MANIPULATION
*/
__declspec(dllexport) SQRESULT Sqvm_ArrayAppend(CSquirrelVM* vmc, SQInteger Idx)
{
	return sq_arrayappend( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_ArrayPop(CSquirrelVM* vmc, SQInteger Idx, SQBool PushVal )
{
	return sq_arraypop( vmc->GetVM(), Idx, PushVal );
}
__declspec(dllexport) SQRESULT Sqvm_ArrayResize(CSquirrelVM* vmc, SQInteger Idx, SQInteger NewSize )
{
	return sq_arrayresize( vmc->GetVM(), Idx, NewSize );
}
__declspec(dllexport) SQRESULT Sqvm_ArrayReverse(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_arrayreverse( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_Clone(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_clone( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_CreateSlot(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_createslot( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_DeleteSlot(CSquirrelVM* vmc, SQInteger Idx, SQBool PushValue )
{
	return sq_deleteslot( vmc->GetVM(), Idx, PushValue );
}
__declspec(dllexport) SQRESULT Sqvm_Get(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_get( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_GetAttributes(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_getattributes( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_GetClass(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_getclass( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_GetDelegate(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_getdelegate( vmc->GetVM(), Idx );
}
__declspec(dllexport) const SQChar * Sqvm_GetFreeVariable(CSquirrelVM* vmc, SQInteger Idx, SQInteger nval )
{
	return sq_getfreevariable( vmc->GetVM(), Idx, nval );
}
__declspec(dllexport) SQRESULT Sqvm_GetWeakRefVal(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_getweakrefval( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_Next(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_next( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_RawDeleteSlot(CSquirrelVM* vmc, SQInteger Idx, SQBool PushVal )
{
	return sq_rawdeleteslot( vmc->GetVM(), Idx, PushVal );
}
__declspec(dllexport) SQRESULT Sqvm_RawGet(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_rawget( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_RawSet(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_rawset( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_Set(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_set( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_SetAttributes(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_setattributes( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_SetDelegate(CSquirrelVM* vmc, SQInteger Idx )
{
	return sq_setdelegate( vmc->GetVM(), Idx );
}
__declspec(dllexport) SQRESULT Sqvm_SetFreeVariable(CSquirrelVM* vmc, SQInteger Idx, SQInteger nval )
{
	return sq_setfreevariable( vmc->GetVM(), Idx, nval );
}
__declspec(dllexport) void Sqvm_WeakRef(CSquirrelVM* vmc, SQInteger Idx )
{
	sq_weakref( vmc->GetVM(), Idx );
}


/*
** ByteCode Serialization
*/
__declspec(dllexport) SQRESULT Sqvm_ReadClosure(CSquirrelVM* vmc, SQREADFUNC readf, SQUserPointer up)
{
	return sq_readclosure( vmc->GetVM(), readf, up );
}
__declspec(dllexport) SQRESULT Sqvm_WriteClosure(CSquirrelVM* vmc, SQWRITEFUNC writef, SQUserPointer up)
{
	return sq_readclosure( vmc->GetVM(), writef, up );
}

/*
** RAW OBJECT HANDLING
*/
__declspec(dllexport) void Sqvm_AddRef(CSquirrelVM* vmc, HSQOBJECT *po)
{
	sq_addref( vmc->GetVM(), po);
}
/* FIXME: ???
__declspec(dllexport) SQRESULT Sqvm_GetObjTypeTag(HSQOBJECT *o, SQUserPointer *typetag)
{
	return sq_getobjtypetag( o, typetag);
}
*/
__declspec(dllexport) SQRESULT Sqvm_GetStackObj(CSquirrelVM* vmc, SQInteger Idx, HSQOBJECT *po)
{
	return sq_getstackobj( vmc->GetVM(), Idx, po );
}
__declspec(dllexport) SQBool Sqvm_ObjToBool(HSQOBJECT *po)
{
	return sq_objtobool( po );
}
__declspec(dllexport) SQFloat Sqvm_ObjToFloat(HSQOBJECT *po)
{
	return sq_objtofloat( po );
}
__declspec(dllexport) SQInteger Sqvm_ObjToInteger(HSQOBJECT *po)
{
	return sq_objtointeger( po );
}
__declspec(dllexport) const SQChar * Sqvm_ObjToString(HSQOBJECT *po)
{
	return sq_objtostring( po );
}
__declspec(dllexport) void Sqvm_PushObject(CSquirrelVM* vmc, HSQOBJECT obj)
{
	sq_pushobject( vmc->GetVM(), obj );
}
__declspec(dllexport) SQBool Sqvm_Release(CSquirrelVM* vmc, HSQOBJECT *po)
{
	return sq_release( vmc->GetVM(), po );
}
__declspec(dllexport) void Sqvm_ResetObject(HSQOBJECT *po)
{
	sq_resetobject( po );
}

/*
** DEBUG INTERFACE
*/
__declspec(dllexport) void Sqvm_SetDebugHook(CSquirrelVM* vmc)
{
	sq_setdebughook( vmc->GetVM() );
}
__declspec(dllexport) SQRESULT Sqvm_StackInfos(CSquirrelVM* vmc, SQInteger Idx, SQStackInfos *si)
{
	return sq_stackinfos( vmc->GetVM(), Idx, si );
}

/*
** Success Failed API
*/
__declspec(dllexport) bool Sqvm_Success(SQRESULT result)
{
	return SQ_SUCCEEDED(result);
}
__declspec(dllexport) bool Sqvm_Failed(SQRESULT result)
{
	return SQ_FAILED(result);
}















/*
**
** RAW API EXPOSED
**
*/

__declspec(dllexport) void SqClose(HSQUIRRELVM vm)
{
	sq_close(vm);
}

__declspec(dllexport) SQUserPointer SqGetForeignPtr(HSQUIRRELVM vm)
{
	return sq_getforeignptr(vm);
}

__declspec(dllexport) SQPRINTFUNCTION SqGetPrintFunc(HSQUIRRELVM vm)
{
	return sq_getprintfunc(vm);
}

__declspec(dllexport) SQPRINTFUNCTION SqGetErrorFunc(HSQUIRRELVM vm)
{
	return sq_geterrorfunc(vm);
}

__declspec(dllexport) SQInteger SqGetVMState(HSQUIRRELVM vm)
{
	return sq_getvmstate(vm);
}

__declspec(dllexport) void SqMove(HSQUIRRELVM srcVM, HSQUIRRELVM tarVM, SQInteger idx)
{
	return sq_move( srcVM, tarVM, idx);
}

__declspec(dllexport) HSQUIRRELVM SqNewThread(HSQUIRRELVM friendvm, SQInteger intialStackSize)
{
	return sq_newthread( friendvm, intialStackSize );
}

__declspec(dllexport) HSQUIRRELVM SqOpen( int StackSize )
{
	return sq_open( StackSize );
}

__declspec(dllexport) void SqPushRegistryTable(HSQUIRRELVM vm)
{
	sq_pushregistrytable( vm );
}

__declspec(dllexport) void SqPushRootTable(HSQUIRRELVM vm)
{
	sq_pushroottable( vm );
}

__declspec(dllexport) void SqSetErrorHandler(HSQUIRRELVM vm)
{
	sq_seterrorhandler( vm );
}

__declspec(dllexport) void SqSetForeignPtr(HSQUIRRELVM vm, SQUserPointer p)
{
	sq_setforeignptr(vm, p);
}

__declspec(dllexport) void SqSetPrintFunc(HSQUIRRELVM vm, SQPRINTFUNCTION prnFn, SQPRINTFUNCTION errFn)
{
	sq_setprintfunc(vm, prnFn, errFn);
}

__declspec(dllexport) void SqSetRootTable(HSQUIRRELVM vm)
{
	sq_setroottable( vm );
}

__declspec(dllexport) SQRESULT SqSuspendVM(HSQUIRRELVM vm)
{
	return sq_suspendvm( vm );
}

__declspec(dllexport) SQRESULT SqWakeUpVM(HSQUIRRELVM vm, SQBool resumedret, SQBool retval, SQBool RaiseError,SQBool ThrowError)
{
	return sq_wakeupvm( vm, resumedret, retval, RaiseError, ThrowError );
}

/*
** COMPILER
*/
__declspec(dllexport) SQRESULT SqCompileReader(HSQUIRRELVM vm, SQLEXREADFUNC ReadFunc, SQUserPointer UserPtr, char *SourceName, SQBool RaiseError )
{
	return sq_compile( vm, ReadFunc, UserPtr, SourceName, RaiseError);
}
__declspec(dllexport) SQRESULT SqCompileBuffer(HSQUIRRELVM vm, char *Buffer, int BufferSize, char *SourceName, SQBool RaiseError )
{
	return sq_compilebuffer( vm, Buffer, BufferSize, SourceName, RaiseError);
}
__declspec(dllexport) void SqEnableDebugInfo(HSQUIRRELVM vm, SQBool DebugInfo )
{
	sq_enabledebuginfo( vm, DebugInfo );
}
__declspec(dllexport) void SqSetCompilerErrorHandler(HSQUIRRELVM vm, SQCOMPILERERROR f )
{
	sq_setcompilererrorhandler( vm, f );
}

/*
** STACK OPERATIONS
*/


__declspec(dllexport) SQInteger SqCmp(HSQUIRRELVM vm)
{
	return sq_cmp( vm );
}
__declspec(dllexport) SQInteger SqGetTop(HSQUIRRELVM vm)
{
	return sq_gettop( vm );
}
__declspec(dllexport) void SqPop(HSQUIRRELVM vm, SQInteger Count)
{
	sq_pop( vm, Count );
}
__declspec(dllexport) void SqPopTop(HSQUIRRELVM vm)
{
	sq_poptop( vm );
}
__declspec(dllexport) void SqPush(HSQUIRRELVM vm, SQInteger Count)
{
	sq_push( vm, Count );
}
__declspec(dllexport) void SqRemove(HSQUIRRELVM vm, SQInteger Count)
{
	sq_remove( vm, Count );
}
__declspec(dllexport) void SqReserveStack(HSQUIRRELVM vm, SQInteger Count)
{
	sq_reservestack( vm, Count );
}

__declspec(dllexport) void SqSetTop(HSQUIRRELVM vm, SQInteger Count)
{
	sq_settop( vm, Count );
}


/*
** Object Creation and Handling
*/

__declspec(dllexport) SQRESULT SqCreateInstance(HSQUIRRELVM vm, SQInteger Idx)
{
	return sq_createinstance( vm, Idx );
}
__declspec(dllexport) SQRESULT SqGetBool(HSQUIRRELVM vm, SQInteger Idx, SQBool *Result)
{
	return sq_getbool( vm, Idx, Result);
}
__declspec(dllexport) SQRESULT SqGetClosureInfo(HSQUIRRELVM vm, SQInteger Idx, 
												SQUnsignedInteger *nparams,
												SQUnsignedInteger *nfreevars)
{
	return sq_getclosureinfo( vm, Idx, nparams, nfreevars );
}

__declspec(dllexport) SQRESULT SqGetFloat(HSQUIRRELVM vm, SQInteger Idx, SQFloat *Result)
{
	return sq_getfloat( vm, Idx, Result);
}
__declspec(dllexport) SQRESULT SqGetInstanceUp(HSQUIRRELVM vm, SQInteger Idx, 
											   SQUserPointer *up, SQUserPointer typeTag )
{
	return sq_getinstanceup( vm, Idx, up, typeTag);
}
__declspec(dllexport) SQRESULT SqGetInteger(HSQUIRRELVM vm, SQInteger Idx, SQInteger *Result)
{
	return sq_getinteger( vm, Idx, Result);
}
__declspec(dllexport) SQChar * SqGetScratchPad(HSQUIRRELVM vm, SQInteger minsize)
{
	return sq_getscratchpad( vm, minsize );
}
__declspec(dllexport) SQInteger SqGetSize(HSQUIRRELVM vm, SQInteger Idx)
{
	return sq_getsize( vm, Idx);
}
__declspec(dllexport) SQInteger SqGetString(HSQUIRRELVM vm, SQInteger Idx, const SQChar **c)
{
	return sq_getstring( vm, Idx, c);
}
__declspec(dllexport) SQInteger SqGetThread(HSQUIRRELVM vm, SQInteger Idx, HSQUIRRELVM *v)
{
	return sq_getthread( vm, Idx, v);
}
__declspec(dllexport) SQObjectType SqGetType(HSQUIRRELVM vm, SQInteger Idx)
{
	return sq_gettype( vm, Idx );
}
__declspec(dllexport) SQRESULT SqGetTypeTag(HSQUIRRELVM vm, SQInteger Idx, SQUserPointer *typetag)
{
	return sq_gettypetag( vm, Idx, typetag );
}
__declspec(dllexport) SQRESULT SqGetUserData(HSQUIRRELVM vm, SQInteger Idx, 
											 SQUserPointer *p, SQUserPointer *typetag)
{
	return sq_getuserdata( vm, Idx, p, typetag );
}
__declspec(dllexport) SQRESULT SqGetUserPointer(HSQUIRRELVM vm, SQInteger Idx, SQUserPointer *p)
{
	return sq_getuserpointer( vm, Idx, p );
}
__declspec(dllexport) void SqNewArray(HSQUIRRELVM vm, SQInteger Size)
{
	sq_newarray( vm, Size );
}
__declspec(dllexport) SQRESULT SqNewClass(HSQUIRRELVM vm, SQBool HasBaseClass)
{
	return sq_newclass( vm, HasBaseClass );
}
__declspec(dllexport) void SqNewClosure(HSQUIRRELVM vm, SQFUNCTION func, SQInteger nfreevars )
{
	sq_newclosure( vm, func, nfreevars );
}
__declspec(dllexport) void SqNewTable(HSQUIRRELVM vm)
{
	sq_newtable( vm );
}
__declspec(dllexport) SQUserPointer SqNewUserData(HSQUIRRELVM vm, SQUnsignedInteger Size)
{
	return sq_newuserdata( vm, Size );
}
__declspec(dllexport) void SqPushBool(HSQUIRRELVM vm, SQBool Value )
{
	sq_pushbool( vm, Value );
}
__declspec(dllexport) void SqPushFloat(HSQUIRRELVM vm, SQFloat Value )
{
	sq_pushfloat( vm, Value );
}
__declspec(dllexport) void SqPushInteger(HSQUIRRELVM vm, SQInteger Value )
{
	sq_pushinteger( vm, Value );
}
__declspec(dllexport) void SqPushNull(HSQUIRRELVM vm)
{
	sq_pushnull( vm );
}
__declspec(dllexport) void SqPushString(HSQUIRRELVM vm, const SQChar *s, SQInteger len)
{
	sq_pushstring( vm, s, len );
}
__declspec(dllexport) void SqPushUserPointer(HSQUIRRELVM vm, SQUserPointer p)
{
	sq_pushuserpointer( vm, p );
}
__declspec(dllexport) SQRESULT SqSetInstanceUp(HSQUIRRELVM vm, SQInteger Idx, SQUserPointer up)
{
	return sq_setinstanceup( vm, Idx, up );
}
__declspec(dllexport) SQRESULT SqSetNativeClosureName(HSQUIRRELVM vm, SQInteger Idx, const SQChar *name)
{
	return sq_setnativeclosurename( vm, Idx, name );
}
__declspec(dllexport) SQRESULT SqSetParamsCheck(HSQUIRRELVM vm, SQInteger nparamscheck, const SQChar *TypeMask)
{
	return sq_setparamscheck( vm, nparamscheck, TypeMask );
}
__declspec(dllexport) void SqSetReleaseHook(HSQUIRRELVM vm, SQInteger Idx, SQRELEASEHOOK Hook)
{
	sq_setreleasehook( vm, Idx, Hook );
}
__declspec(dllexport) SQRESULT SqSetTypeTag(HSQUIRRELVM vm, SQInteger Idx, SQUserPointer TypeTag)
{
	return sq_settypetag( vm, Idx, TypeTag );
}
__declspec(dllexport) SQRESULT SqCall(HSQUIRRELVM vm, SQInteger Params, SQBool RetVal, SQBool RaiseError)
{
	return sq_call( vm, Params, RetVal, RaiseError );
}
__declspec(dllexport) void SqGetLastError(HSQUIRRELVM vm)
{
	sq_getlasterror( vm );
}
__declspec(dllexport) const SQChar * SqGetLocal(HSQUIRRELVM vm, 
												SQUnsignedInteger level, 
												SQUnsignedInteger nseq )
{
	return sq_getlocal( vm, level, nseq );
}
__declspec(dllexport) void SqResetError(HSQUIRRELVM vm)
{
	sq_reseterror( vm );
}
__declspec(dllexport) SQRESULT SqResume(HSQUIRRELVM vm, SQBool RetVal, SQBool RaiseError)
{
	return sq_resume( vm, RetVal, RaiseError );
}
__declspec(dllexport) SQRESULT SqThrowError(HSQUIRRELVM vm, const SQChar *err)
{
	return sq_throwerror( vm, err );
}


/*
** OBJECTS MANIPULATION
*/
__declspec(dllexport) SQRESULT SqArrayAppend(HSQUIRRELVM vm, SQInteger Idx)
{
	return sq_arrayappend( vm, Idx );
}
__declspec(dllexport) SQRESULT SqArrayPop(HSQUIRRELVM vm, SQInteger Idx, SQBool PushVal )
{
	return sq_arraypop( vm, Idx, PushVal );
}
__declspec(dllexport) SQRESULT SqArrayResize(HSQUIRRELVM vm, SQInteger Idx, SQInteger NewSize )
{
	return sq_arrayresize( vm, Idx, NewSize );
}
__declspec(dllexport) SQRESULT SqArrayReverse(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_arrayreverse( vm, Idx );
}
__declspec(dllexport) SQRESULT SqClone(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_clone( vm, Idx );
}
__declspec(dllexport) SQRESULT SqCreateSlot(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_createslot( vm, Idx );
}
__declspec(dllexport) SQRESULT SqDeleteSlot(HSQUIRRELVM vm, SQInteger Idx, SQBool PushValue )
{
	return sq_deleteslot( vm, Idx, PushValue );
}
__declspec(dllexport) SQRESULT SqGet(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_get( vm, Idx );
}
__declspec(dllexport) SQRESULT SqGetAttributes(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_getattributes( vm, Idx );
}
__declspec(dllexport) SQRESULT SqGetClass(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_getclass( vm, Idx );
}
__declspec(dllexport) SQRESULT SqGetDelegate(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_getdelegate( vm, Idx );
}
__declspec(dllexport) const SQChar * SqGetFreeVariable(HSQUIRRELVM vm, SQInteger Idx, SQInteger nval )
{
	return sq_getfreevariable( vm, Idx, nval );
}
__declspec(dllexport) SQRESULT SqGetWeakRefVal(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_getweakrefval( vm, Idx );
}
__declspec(dllexport) SQRESULT SqNext(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_next( vm, Idx );
}
__declspec(dllexport) SQRESULT SqRawDeleteSlot(HSQUIRRELVM vm, SQInteger Idx, SQBool PushVal )
{
	return sq_rawdeleteslot( vm, Idx, PushVal );
}
__declspec(dllexport) SQRESULT SqRawGet(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_rawget( vm, Idx );
}
__declspec(dllexport) SQRESULT SqRawSet(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_rawset( vm, Idx );
}
__declspec(dllexport) SQRESULT SqSet(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_set( vm, Idx );
}
__declspec(dllexport) SQRESULT SqSetAttributes(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_setattributes( vm, Idx );
}
__declspec(dllexport) SQRESULT SqSetDelegate(HSQUIRRELVM vm, SQInteger Idx )
{
	return sq_setdelegate( vm, Idx );
}
__declspec(dllexport) SQRESULT SqSetFreeVariable(HSQUIRRELVM vm, SQInteger Idx, SQInteger nval )
{
	return sq_setfreevariable( vm, Idx, nval );
}
__declspec(dllexport) void SqWeakRef(HSQUIRRELVM vm, SQInteger Idx )
{
	sq_weakref( vm, Idx );
}


/*
** ByteCode Serialization
*/
__declspec(dllexport) SQRESULT SqReadClosure(HSQUIRRELVM vm, SQREADFUNC readf, SQUserPointer up)
{
	return sq_readclosure( vm, readf, up );
}
__declspec(dllexport) SQRESULT SqWriteClosure(HSQUIRRELVM vm, SQWRITEFUNC writef, SQUserPointer up)
{
	return sq_readclosure( vm, writef, up );
}

/*
** RAW OBJECT HANDLING
*/
__declspec(dllexport) void SqAddRef(HSQUIRRELVM vm, HSQOBJECT *po)
{
	sq_addref( vm, po);
}
/* FIXME: ???
__declspec(dllexport) SQRESULT SqGetObjTypeTag(HSQOBJECT *o, SQUserPointer *typetag)
{
	return sq_getobjtypetag( o, typetag);
}
*/
__declspec(dllexport) SQRESULT SqGetStackObj(HSQUIRRELVM vm, SQInteger Idx, HSQOBJECT *po)
{
	return sq_getstackobj( vm, Idx, po );
}
__declspec(dllexport) SQBool SqObjToBool(HSQOBJECT *po)
{
	return sq_objtobool( po );
}
__declspec(dllexport) SQFloat SqObjToFloat(HSQOBJECT *po)
{
	return sq_objtofloat( po );
}
__declspec(dllexport) SQInteger SqObjToInteger(HSQOBJECT *po)
{
	return sq_objtointeger( po );
}
__declspec(dllexport) const SQChar * SqObjToString(HSQOBJECT *po)
{
	return sq_objtostring( po );
}
__declspec(dllexport) void SqPushObject(HSQUIRRELVM vm, HSQOBJECT obj)
{
	sq_pushobject( vm, obj );
}
__declspec(dllexport) SQBool SqRelease(HSQUIRRELVM vm, HSQOBJECT *po)
{
	return sq_release( vm, po );
}
__declspec(dllexport) void SqResetObject(HSQOBJECT *po)
{
	sq_resetobject( po );
}

/*
** DEBUG INTERFACE
*/
__declspec(dllexport) void SqSetDebugHook(HSQUIRRELVM vm)
{
	sq_setdebughook( vm );
}
__declspec(dllexport) SQRESULT SqStackInfos(HSQUIRRELVM vm, SQInteger Idx, SQStackInfos *si)
{
	return sq_stackinfos( vm, Idx, si );
}

/*
** Success Failed API
*/
__declspec(dllexport) bool SqSuccess(SQRESULT result)
{
	return SQ_SUCCEEDED(result);
}
__declspec(dllexport) bool SqFailed(SQRESULT result)
{
	return SQ_FAILED(result);
}


SQChar bufPrint[1025];
void bypass_print_function(HSQUIRRELVM vm, const SQChar *s, va_list arglist) 
{
#ifdef SQUNICODE
//    int count = wsprintfW(bufPrint,s, arglist); 
	int count = swprintf_s(bufPrint,1024,s,arglist);
#else
//    int count = wsprintf(bufPrint,s, arglist);
	int count = sprintf_s(bufPrint,1024,s,arglist);
#endif

	SQInteger top = sq_gettop(vm);

	sq_pushroottable(vm);
	sq_pushstring(vm,"__alt_print_fn_ptr",18);
    SQInteger result = sq_rawget(vm,-2);

	if (SQ_SUCCEEDED(result))
	{ 
		SQUserPointer ptr = 0;
		result = sq_getuserpointer(vm,-1, &ptr); 
		if ( SQ_SUCCEEDED(result) )
		{
			SQVM_PRINT_STRING prnFn = (SQVM_PRINT_STRING)ptr;
			if ( prnFn != 0 )
				prnFn(bufPrint);
		}
	}

	while (sq_gettop(vm)>top)
		sq_pop(vm,1);	
}

SQChar bufError[1025];
void bypass_error_function(HSQUIRRELVM vm, const SQChar *s, va_list arglist) 
{
#ifdef SQUNICODE
//    int count = wsprintfW(bufPrint,s, arglist); 
	int count = swprintf_s(bufPrint,1024,s,arglist);
#else
//    int count = wsprintf(bufPrint,s, arglist);
	int count = sprintf_s(bufPrint,1024,s,arglist);
#endif

	SQInteger top = sq_gettop(vm);

	sq_pushroottable(vm);
	sq_pushstring(vm,"__alt_error_fn_ptr",18);
    SQInteger result = sq_rawget(vm,-2);

	if (SQ_SUCCEEDED(result))
	{ 
		SQUserPointer ptr = 0;
		result = sq_getuserpointer(vm,-1, &ptr); 
		if ( SQ_SUCCEEDED(result) )
		{
			SQVM_PRINT_STRING prnFn = (SQVM_PRINT_STRING)ptr;
			if ( prnFn != 0 )
				prnFn(bufPrint);
		}
	}

	while (sq_gettop(vm)>top)
		sq_pop(vm,1);	
} 

__declspec(dllexport) SQInteger SqSetCompatiblePrintFunction(HSQUIRRELVM vm, SQUserPointer usrFnPtr)
{
	SQInteger top = sq_gettop(vm);
	sq_pushroottable(vm);
	sq_pushstring(vm,"__alt_print_fn_ptr",18);
	sq_pushuserpointer(vm, usrFnPtr);
	SQInteger result = sq_rawset(vm, -3);
	while ( sq_gettop(vm) > top )
		sq_pop(vm,1);
	if ( SqSuccess(result) )
		sq_setprintfunc(vm,(SQPRINTFUNCTION)&bypass_print_function,sq_geterrorfunc(vm));
	return result;
}
__declspec(dllexport) SQUserPointer SqGetCompatiblePrintFunction(HSQUIRRELVM vm)
{
    SQInteger top = sq_gettop(vm);
	sq_pushroottable(vm);
	sq_pushstring(vm,"__alt_print_fn_ptr",18);
    SQInteger result = sq_rawget(vm,-2);

	SQUserPointer ptr = 0;

	if (SQ_SUCCEEDED(result))
		result = sq_getuserpointer(vm,-1, &ptr); 

	while (sq_gettop(vm)>top)
		sq_pop(vm,1);	

	return ptr;
}
__declspec(dllexport) SQInteger SqSetCompatibleErrorFunction(HSQUIRRELVM vm, SQUserPointer usrFnPtr)
{
	SQInteger top = sq_gettop(vm);
	sq_pushroottable(vm);
	sq_pushstring(vm,"__alt_error_fn_ptr",18);
	sq_pushuserpointer(vm, usrFnPtr);
	SQInteger result = sq_rawset(vm, -3);
	while ( sq_gettop(vm) > top )
		sq_pop(vm,1);
	if ( SqSuccess(result) )
		sq_setprintfunc(vm,sq_getprintfunc(vm),(SQPRINTFUNCTION)&bypass_error_function);
	return result;
}
__declspec(dllexport) SQUserPointer SqGetCompatibleErrorFunction(HSQUIRRELVM vm)
{
    SQInteger top = sq_gettop(vm);
	sq_pushroottable(vm);
	sq_pushstring(vm,"__alt_error_fn_ptr",18);
    SQInteger result = sq_rawget(vm,-2);

	SQUserPointer ptr = 0;

	if (SQ_SUCCEEDED(result))
		result = sq_getuserpointer(vm,-1, &ptr); 

	while (sq_gettop(vm)>top)
		sq_pop(vm,1);	

	return ptr;
}
__declspec(dllexport) SQInteger SqSetCompatiblePrintFunctions(HSQUIRRELVM vm, SQUserPointer usrPrintFnPtr, SQUserPointer usrErrorFnPtr)
{
	SQInteger result = SqSetCompatiblePrintFunction(vm,usrPrintFnPtr);
	if ( SQ_SUCCEEDED(result) )
	{
		result = SqSetCompatibleErrorFunction(vm,usrErrorFnPtr);
		return SetInteger(vm,"FOOFOOBAR",3535);
	}
	else
	{
		SetInteger(vm,"FOOFOOBAR",-10);
	}
	return result;
}

SQInteger SetString(HSQUIRRELVM vm, SQChar *name, const SQChar *value)
{
    SQInteger top = sq_gettop(vm);
	sq_pushroottable(vm);
#ifdef SQUNICODE
	sq_pushstring(vm,name,wcslen(name));
	sq_pushstring(vm,value,wcslen(value));
#else
	sq_pushstring(vm,name,strlen(name));
	sq_pushstring(vm,value,strlen(value));
#endif
	SQInteger result = sq_rawset(vm, -3);
	while (sq_gettop(vm)>top)
		sq_pop(vm,1);
	return result;
}

SQInteger SetInteger(HSQUIRRELVM vm, SQChar *name, SQInteger value)
{
    SQInteger top = sq_gettop(vm);
	sq_pushroottable(vm);
#ifdef SQUNICODE
	sq_pushstring(vm,name,wcslen(name));
	sq_pushstring(vm,value,wcslen(value));
#else
	sq_pushstring(vm,name,strlen(name));
	sq_pushinteger(vm,value);
#endif
	SQInteger result = sq_rawset(vm, -3);
	while (sq_gettop(vm)>top)
		sq_pop(vm,1);	
	return result;
}


